package scooper.cn.sc_base.log;

import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * @author litingwei
 * @date 2019/5/14.
 */
public class LogConfig {
    /** 包名，用于匹配打印日志的方法
     * 一个包名包含另一个包名时（以另一个包名开头且更长）以长的包名优先,
     * 包名不能重复，包名为空字符串时，打印未匹配到的日志 **/
    private String packageName;
    /** 打印日志的目录 **/
    private String directory;
    /** 打印的日志的名称前缀，默认：info **/
    private String fileNamePrefix;
    /** 打印的日志的后缀，默认：log **/
    private String fileNameSuffix;
    /** 日期格式，按日分文件有效 **/
    private SimpleDateFormat dateFormat;
    /** 按日期分文件模式
     * true：日志按 前缀_日期格式[_分文件数].后缀 生成文件
     * false：日志按 前缀.后缀 生成文件
     **/
    private boolean daily;
    /** 最大文件大小，每次初始化时检查文件大小 **/
    private long maxSizeMeg;
    /** 保存期时长（单位：天），按日分文件模式有效 **/
    private int retentionPeriodDay;

    private LogConfig() {}

    public String getPackageName() {
        return packageName;
    }

    public String getDirectory() {
        return directory;
    }

    public String getFileNamePrefix() {
        return fileNamePrefix;
    }

    public String getFileNameSuffix() {
        return fileNameSuffix;
    }

    public SimpleDateFormat getDateFormat() {
        return dateFormat;
    }

    public boolean isDaily() {
        return daily;
    }

    public long getMaxSizeMeg() {
        return maxSizeMeg;
    }

    public int getRetentionPeriodDay() {
        return retentionPeriodDay;
    }

    public File getLogDirFile() {
        File logDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + directory);
        if (!logDir.exists()) {
            if (!logDir.mkdirs()) {
                return null;
            }
        }
        return logDir;
    }

    public File getLogFile() {
        File logFile = null;
        try {
            long maxSize = maxSizeMeg * 1024 * 1024;
            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                return null;
            }
            File logDir = getLogDirFile();
            if (daily) {
                String dateStr = dateFormat.format(new Date());
                int i = 0;
                do {
                    final String fileName;
                    if (i == 0) {
                        fileName = fileNamePrefix + "_" + dateStr + "." + fileNameSuffix;
                    } else {
                        fileName = fileNamePrefix + "_" + dateStr + "_" + i + "." + fileNameSuffix;
                    }
                    logFile = new File(logDir, fileName);
                    if (logFile.exists() && !logFile.isFile()) {
                        throw new RuntimeException("Log file [" + logFile.getAbsolutePath() + "] is not file!");
                    }
                    i++;
                } while (logFile.exists() && logFile.length() >= maxSize);
            } else {
                String fileName = fileNamePrefix + "." + fileNameSuffix;
                logFile = new File(logDir, fileName);
            }
            if (!logFile.exists()) {
                try {
                    if (!logFile.createNewFile()) {
                        return null;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        } catch (Exception e) {}
        return logFile;
    }

    @Override
    public String toString() {
        return "LogConfig{" +
                "packageName='" + packageName + '\'' +
                ", directory='" + directory + '\'' +
                ", fileNamePrefix='" + fileNamePrefix + '\'' +
                ", fileNameSuffix='" + fileNameSuffix + '\'' +
                ", dateFormat=" + dateFormat +
                ", daily=" + daily +
                ", maxSizeMeg=" + maxSizeMeg +
                ", retentionPeriodDay=" + retentionPeriodDay +
                '}';
    }

    public static class Builder {
        private String packageName = "";
        private String directory;
        private String fileNamePrefix = "info";
        private String fileNameSuffix = "log";
        private String dateFormat = "yyyy-MM-dd";
        private boolean daily = false;
        private long maxSizeMeg = 4;
        private int retentionPeriodDay = 15;

        public LogConfig build() {
            LogConfig config = new LogConfig();
            if (!TextUtils.isEmpty(packageName)) {
                config.packageName = packageName;
            } else {
                config.packageName = "";
            }
            if (TextUtils.isEmpty(directory)) {
                config.directory = "scooper" + File.separator + "log";
            } else {
                config.directory = directory;
            }
            if (!TextUtils.isEmpty(fileNamePrefix)) {
                config.fileNamePrefix = fileNamePrefix;
            }
            if (!TextUtils.isEmpty(fileNameSuffix)) {
                config.fileNameSuffix = fileNameSuffix;
            }
            config.daily = daily;
            config.maxSizeMeg = maxSizeMeg;
            config.retentionPeriodDay = retentionPeriodDay;
            if (daily) {
                config.dateFormat = new SimpleDateFormat(dateFormat, Locale.getDefault());
            }
            Log.e(LogProcessClient.class.getCanonicalName(), config.toString());
            return config;
        }

        public String getPackageName() {
            return packageName;
        }

        public Builder setPackageName(String packageName) {
            this.packageName = packageName;
            return this;
        }

        public String getDirectory() {
            return directory;
        }

        public Builder setDirectory(String directory) {
            this.directory = directory;
            return this;
        }

        public String getFileNamePrefix() {
            return fileNamePrefix;
        }

        public Builder setFileNamePrefix(String fileNamePrefix) {
            this.fileNamePrefix = fileNamePrefix;
            return this;
        }

        public String getFileNameSuffix() {
            return fileNameSuffix;
        }

        public Builder setFileNameSuffix(String fileNameSuffix) {
            this.fileNameSuffix = fileNameSuffix;
            return this;
        }

        public String getDateFormat() {
            return dateFormat;
        }

        public Builder setDateFormat(String dateFormat) {
            this.dateFormat = dateFormat;
            return this;
        }

        public boolean isDaily() {
            return daily;
        }

        public Builder setDaily(boolean daily) {
            this.daily = daily;
            return this;
        }

        public long getMaxSizeMeg() {
            return maxSizeMeg;
        }

        public Builder setMaxSizeMeg(long maxSizeMeg) {
            if (maxSizeMeg <= 0) {
                throw new RuntimeException("Max size of log config must > 0");
            }
            this.maxSizeMeg = maxSizeMeg;
            return this;
        }

        public int getRetentionPeriodDay() {
            return retentionPeriodDay;
        }

        public Builder setRetentionPeriodDay(int retentionPeriodDay) {
            if (maxSizeMeg < 1) {
                throw new RuntimeException("Retention period of log config must > 1");
            }
            this.retentionPeriodDay = retentionPeriodDay;
            return this;
        }
    }
}
